﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VectorDraw.Professional.vdPrimaries;
using VectorDraw.Professional.vdFigures;
using System.Data;
using VectorDraw.Geometry;

namespace PDNPAS
{
    class StaticMethods
    {
        /// <summary>
        /// 求线性回归系数a、b。公式y=a+bx
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public static void GetLinearRegressionCoeffficient(DataTable dt, out double a, out double b)//第一列为自变量，第二列为因变量
        {
            int n = dt.Rows.Count;
            int[] years = new int[n];
            double[] loads = new double[n];
            for (int i = 0; i < n; i++)
            {
                years[i] = Convert.ToInt32(dt.Rows[i].ItemArray[0]);
                loads[i] = Convert.ToDouble(dt.Rows[i].ItemArray[1]);
            }
            double sumOfXY = 0;
            double avgOfX = 0;
            double avgOfY = 0;
            int sumOfXX = 0;
            for (int i = 0; i < n; i++)
            {
                sumOfXY += years[i] * loads[i];
                avgOfX += years[i];
                avgOfY += loads[i];
                sumOfXX += years[i] * years[i];
            }
            avgOfX = avgOfX / n;
            avgOfY = avgOfY / n;

            b = (sumOfXY - n * avgOfX * avgOfY) / (sumOfXX - n * avgOfX * avgOfX);
            a = avgOfY - b * avgOfX;        
        }

        /// <summary>
        /// 根据controlNum来获取开关站，环网站或变电站的名称
        /// </summary>
        /// <param name="controlNumP"></param>
        /// <param name="subStListP"></param>
        /// <param name="switchStListP"></param>
        /// <param name="loopstListP"></param>
        /// <returns></returns>
        public static string GetStNameByControlNum(int controlNumP, List<Substation> subStListP, List<SwitchStation> switchStListP, List<Loopstation> loopstListP)
        {
            for (int i = 0; i < subStListP.Count; i++)
            {
                if (subStListP[i].ControlNum == controlNumP)
                {
                    return subStListP[i].SubstName;
                }
            }
            for (int i = 0; i < switchStListP.Count; i++)
            {
                if (switchStListP[i].ControlNum == controlNumP)
                {
                    return switchStListP[i].SwitchStName;
                }
            }
            for (int i = 0; i < loopstListP.Count; i++)
            {
                if (loopstListP[i].ControlNum == controlNumP)
                {
                    return loopstListP[i].LoopstName;
                }            
            }
            return "";
        }

        /// <summary>
        /// 求一个变电站的出线数
        /// </summary>
        /// <param name="subst"></param>
        /// <param name="lineList"></param>
        /// <returns></returns>
        public static int GetSubstOutgoingNum(Substation subst,List<Transline> lineList )
        {
            int num = 0;
            for (int i = 0; i < lineList.Count; i++)
            {
                if (lineList[i].StartP == subst.ControlNum || lineList[i].EndP == subst.ControlNum)
                    num++;
            }
            return num;
        }

        /// <summary>
        /// 获取一个图案填充的形心
        /// </summary>
        /// <param name="hatch"></param>
        /// <returns></returns>
        public static gPoint GetHatchCentroid(vdPolyhatch hatch)
        {
            //gPoints points = new gPoints();
            //if (hatch != null)
            //{
            //    VectorDraw.Professional.vdCollections.vdPolyCurves curveCollect = hatch.PolyCurves;

            //    for (int j = 0; j < curveCollect.Count; j++)
            //    {
            //        for (int m = 0; m < curveCollect[j].Count; m++)
            //        {
            //            vdCurve curve = curveCollect[j][m];
            //            points.AddRange(curve.GetSamplePoints(0, 0));
            //        }
            //    }
            //}
            //return points.Centroid(); 

            gPoints points = new gPoints();
            if (hatch != null)
            {
                VectorDraw.Professional.vdCollections.vdPolyCurves curveCollect = hatch.PolyCurves;
                for (int j = 0; j < curveCollect.Count; j++)
                {
                    for (int m = 0; m < curveCollect[j].Count; m++)
                    {
                        vdCurve curve = curveCollect[j][m];
                        gPoints pts = new gPoints();
                        pts.AddRange(curve.GetSamplePoints(0, 0));
                        curve.ECSMatrix.Transform(pts); // fromECS matrix to world
                        points.AddRange(pts);
                    }
                }
            }

            return points.Centroid();
        }

        /// <summary>
        /// 判断一个点是否在多段线内部
        /// </summary>
        /// <param name="point"></param>
        /// <param name="pline"></param>
        /// <returns></returns>
        public static bool isPointInsidePolyline(gPoint point, vdPolyline pline)
        {
            //Create A Region From the Polyline's points
            VectorDraw.Render.Region reg = new VectorDraw.Render.Region(pline.GetSamplePoints(0, 0));
            //Check if a point is inside the polyline or not.
            bool a = reg.IsPointInside(point); 
            return a;        
        }

        /// <summary>
        /// 统计多个地块的面积！！！！！！！要不要考虑同时率
        /// </summary>
        /// <param name="landList"></param>
        /// <returns></returns>
        public static double getTotalLoad(List<Land> landList)
        {
            double totalLoad = 0.0;
            for (int i = 0; i < landList.Count; i++)
            {
                totalLoad += landList[i].LandLoadM;
            }
            return totalLoad;
        }

        /// <summary>
        /// 返回landList中与newLandList所有形心距离和最短的land
        /// </summary>
        /// <param name="landList"></param>
        /// <param name="newLandList"></param>
        /// <returns></returns>
        public static Land getClosestLand(List<Land> landList,List<Land> newLandList)
        {
            Land land = new Land();
            if (landList.Count == 1)
            { 
                return landList[0];
            }
            
            double distance = 0.0;
            gPoint centroid=GetHatchCentroid(landList[0].Myhatch.Hatch);
            for (int i = 0; i < newLandList.Count; i++)
            {
                distance += gPoint.Distance2D(centroid, GetHatchCentroid(newLandList[i].Myhatch.Hatch));               
            }
            land=landList[0];
            for (int i = 1; i < landList.Count; i++)
            {
                double dist = 0.0;
                for (int j = 0; j < newLandList.Count; j++)
                {
                    dist += gPoint.Distance2D(GetHatchCentroid(landList[i].Myhatch.Hatch), GetHatchCentroid(newLandList[j].Myhatch.Hatch));
                }
                if (dist < distance)
                {
                    land = landList[i];
                    distance = dist;
                }
            }
            return land;
        }

        /// <summary>
        /// 在三双规划中，目前只考虑负荷在0.75-2.75MW之间的负荷，返回需要的环网单元数量
        /// </summary>
        /// <param name="totalLoad"></param>
        /// <returns></returns>
        internal static int getLoopstNum(double totalLoad)
        {
            int loopstNum = 0;
            if (totalLoad >= 750000 && totalLoad <= 1500000)
            {
                loopstNum = 1;
            }
            else if (totalLoad > 1500000 && totalLoad <= 2750000)
            {
                loopstNum = 2;
            }

            return loopstNum;
        }
    }
}
